package com.weixin.mp.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weixin.mp.entity.User;
import com.weixin.mp.mapper.UserMapper;
import com.weixin.mp.service.UserService;
import com.weixin.mp.utils.JwtUtils;
import com.weixin.mp.utils.WxCryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Value("${wx.miniapp.appid}")
    private String appid;
    
    @Value("${wx.miniapp.secret}")
    private String secret;
    
    /**
     * 微信小程序授权登录API地址
     */
    private static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
    
    /**
     * 微信小程序获取手机号API地址
     */
    private static final String WX_PHONE_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";
    
    @Override
    public String wxLogin(String code) {
        try {
            log.info("微信登录处理开始，code: {}", code);
            log.info("使用的appid: {}, secret: {}", appid, "***");
            
            // 拼接微信登录URL
            String url = String.format("%s?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                    WX_LOGIN_URL, appid, secret, code);
            
            // 请求微信API
            String result = HttpUtil.get(url);
            log.info("微信登录返回结果: {}", result);
            
            // 解析微信返回的JSON
            JSONObject jsonObject = JSONUtil.parseObj(result);
            
            // 判断微信返回是否成功
            if (jsonObject.containsKey("errcode") && jsonObject.getInt("errcode") != 0) {
                log.error("微信登录失败: {}", jsonObject.getStr("errmsg"));
                return null;
            }
            
            // 获取openid
            String openid = jsonObject.getStr("openid");
            if (openid == null || openid.isEmpty()) {
                log.error("微信登录失败: 未获取到openid");
                return null;
            }
            
            String unionid = jsonObject.getStr("unionid", "");
            log.info("获取到openid: {}, unionid: {}", openid, unionid);
            
            // 获取用户信息，如果不存在则创建
            User user = getUserByOpenid(openid);
            if (user == null) {
                log.info("用户不存在，创建新用户, openid: {}", openid);
                user = new User();
                user.setOpenid(openid);
                user.setUnionid(unionid);
                user.setCreateTime(LocalDateTime.now());
                user.setStatus(0); // 用户状态正常
                user.setDeleted(0); // 未删除
                save(user);
                log.info("新用户注册: {}", openid);
            } else {
                log.info("用户已存在, id: {}, openid: {}", user.getId(), openid);
            }
            
            // 更新登录时间
            user.setLastLoginTime(LocalDateTime.now());
            updateById(user);
            
            // 生成JWT Token
            String token = JwtUtils.generateToken(user.getId(), openid);
            log.info("生成token成功: {}", token);
            
            return token;
        } catch (Exception e) {
            log.error("微信登录异常", e);
            return null;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserInfo(String openid, String nickname, String avatarUrl, Integer gender, 
                               String country, String province, String city) {
        try {
            // 根据openid查询用户
            User user = getUserByOpenid(openid);
            if (user == null) {
                log.error("更新用户信息失败，用户不存在: {}", openid);
                return false;
            }
            
            // 更新用户信息
            user.setNickname(nickname);
            user.setAvatarUrl(avatarUrl);
            user.setGender(gender);
            user.setCountry(country);
            user.setProvince(province);
            user.setCity(city);
            user.setUpdateTime(LocalDateTime.now());
            
            return updateById(user);
        } catch (Exception e) {
            log.error("更新用户信息异常", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveUserPhone(String openid, String phoneNumber) {
        try {
            // 根据openid查询用户
            User user = getUserByOpenid(openid);
            if (user == null) {
                log.error("保存用户手机号失败，用户不存在: {}", openid);
                return false;
            }
            
            // 更新用户手机号
            user.setPhoneNumber(phoneNumber);
            user.setUpdateTime(LocalDateTime.now());
            
            return updateById(user);
        } catch (Exception e) {
            log.error("保存用户手机号异常", e);
            return false;
        }
    }
    
    /**
     * 保存用户手机号相关信息
     * @param openid 用户openid
     * @param phoneNumber 手机号
     * @param countryCode 国家代码
     * @param purePhoneNumber 纯手机号
     * @return 是否保存成功
     */
    public boolean saveUserPhoneInfo(String openid, String phoneNumber, String countryCode, String purePhoneNumber) {
        try {
            // 根据openid查询用户
            User user = getUserByOpenid(openid);
            if (user == null) {
                log.error("保存用户手机号信息失败，用户不存在: {}", openid);
                return false;
            }
            
            // 更新用户手机号信息
            user.setPhoneNumber(phoneNumber);
            user.setCountryCode(countryCode);
            user.setPurePhoneNumber(purePhoneNumber);
            user.setUpdateTime(LocalDateTime.now());
            
            return updateById(user);
        } catch (Exception e) {
            log.error("保存用户手机号信息异常", e);
            return false;
        }
    }
    
    @Override
    public User getUserByOpenid(String openid) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getOpenid, openid);
        wrapper.eq(User::getDeleted, 0);
        return getOne(wrapper);
    }
    
    @Override
    public Map<String, Object> getPhoneNumber(String openid, String code) {
        try {
            log.info("开始获取手机号，openid: {}, code: {}", openid, code);
            
            // 获取用户信息
            User user = getUserByOpenid(openid);
            if (user == null) {
                log.error("获取手机号失败，用户不存在: {}", openid);
                return null;
            }
            
            // 获取access_token
            String tokenUrl = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                    appid, secret);
            String tokenResult = HttpUtil.get(tokenUrl);
            log.info("获取access_token结果: {}", tokenResult);
            
            JSONObject tokenJson = JSONUtil.parseObj(tokenResult);
            if (tokenJson.containsKey("errcode") && tokenJson.getInt("errcode") != 0) {
                log.error("获取access_token失败: {}", tokenJson.getStr("errmsg"));
                return null;
            }
            
            String accessToken = tokenJson.getStr("access_token");
            if (accessToken == null || accessToken.isEmpty()) {
                log.error("获取access_token失败: access_token为空");
                return null;
            }
            
            // 请求获取手机号API
            String phoneUrl = WX_PHONE_URL + "?access_token=" + accessToken;
            // 构造请求体
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("code", code);
            
            // 使用Hutool的Http客户端发送请求
            String phoneResult = HttpUtil.post(phoneUrl, JSONUtil.toJsonStr(paramMap));
            log.info("获取手机号结果: {}", phoneResult);
            
            JSONObject phoneJson = JSONUtil.parseObj(phoneResult);
            if (phoneJson.containsKey("errcode") && phoneJson.getInt("errcode") != 0) {
                log.error("获取手机号失败: errcode={}, errmsg={}", 
                        phoneJson.getInt("errcode"), 
                        phoneJson.getStr("errmsg"));
                return null;
            }
            
            // 获取手机号信息
            JSONObject phoneInfo = phoneJson.getJSONObject("phone_info");
            if (phoneInfo == null) {
                log.error("获取手机号失败: 未获取到手机号信息");
                return null;
            }
            
            String phoneNumber = phoneInfo.getStr("phoneNumber");
            if (phoneNumber == null || phoneNumber.isEmpty()) {
                log.error("获取手机号失败: 手机号为空");
                return null;
            }
            
            String countryCode = phoneInfo.getStr("countryCode", "");
            String purePhoneNumber = phoneInfo.getStr("purePhoneNumber", "");
            log.info("成功获取到手机号信息: phoneNumber={}, countryCode={}, purePhoneNumber={}", 
                    phoneNumber, countryCode, purePhoneNumber);
            
            // 保存手机号完整信息
            boolean saved = saveUserPhoneInfo(openid, phoneNumber, countryCode, purePhoneNumber);
            if (!saved) {
                log.error("保存手机号信息失败");
                return null;
            }
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("phoneNumber", phoneNumber);
            result.put("purePhoneNumber", purePhoneNumber);
            result.put("countryCode", countryCode);
            
            return result;
        } catch (Exception e) {
            log.error("获取手机号异常", e);
            return null;
        }
    }

    // 添加updateUserAvatar实现方法到UserServiceImpl类中
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserAvatar(String openid, String avatarUrl) {
        try {
            // 根据openid查询用户
            User user = getUserByOpenid(openid);
            if (user == null) {
                log.error("更新用户头像失败，用户不存在: {}", openid);
                return false;
            }
            
            // 更新用户头像
            user.setAvatarUrl(avatarUrl);
            user.setUpdateTime(LocalDateTime.now());
            
            return updateById(user);
        } catch (Exception e) {
            log.error("更新用户头像异常", e);
            return false;
        }
    }
} 